package com.lk.server.rpc.handler;

import cn.hutool.core.util.StrUtil;
import com.lk.entity.RequestMessage;
import com.lk.entity.ResponseMessage;
import com.lk.server.register.LocalRegister;
import com.lk.server.util.SpringBeanUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;

/**
 * @author kun.li
 */
@Slf4j
@ChannelHandler.Sharable
public class RequestMessageHandler extends SimpleChannelInboundHandler<RequestMessage> {

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RequestMessage requestMessage) {
        log.debug("{}", requestMessage);

        // 服务端接受到client 发送过来的请求,
        String interfaceName = requestMessage.getInterfaceName();
        String methodName = requestMessage.getMethodName();
        Class[] parameterTypes = requestMessage.getParameterTypes();
        Object[] parameterValue = requestMessage.getParameterValue();
        String version = requestMessage.getVersion();
        String beanName = requestMessage.getBeanName();
        ResponseMessage responseMessage = new ResponseMessage();
        try {
            // 本地注册,这里使用spring来管理 否则需要写一个map <String,Class> 来管理
            // 这里并且没有实现多实现的问题,多实现可以使用版本号来区分
            Object bean;
            if (StrUtil.isNotEmpty(beanName)) {
                bean = getBean(beanName, interfaceName);
            } else {
                bean = version(version, interfaceName);
            }
            Method method = bean.getClass().getMethod(methodName, parameterTypes);
            // 得到返回值
            Object invoke = method.invoke(bean, parameterValue);
            log.info("invoke:{}", invoke);
            responseMessage.setReturnValue(invoke);
            responseMessage.setSequenceId(requestMessage.getSequenceId());
        } catch (Exception e) {
            e.printStackTrace();
            responseMessage.setExceptionValue(new Exception("调用失败"));
        }
        channelHandlerContext.writeAndFlush(responseMessage);
    }



    // 版本号 一个接口有多个实现类时进行区分
    public Object version(String version, String interfaceName) {
        return LocalRegister.getService(interfaceName, version);
    }

    public Object getBean(String name, String interfaceName) throws Exception {
        try {
            return SpringBeanUtil.getBean(name, Class.forName(interfaceName));
        } catch (Exception e) {
            return SpringBeanUtil.getBean(Class.forName(interfaceName));
        }
    }


}
